package com.caiyi.financial.nirvana.sms.gateway.http;

import com.caiyi.financial.nirvana.sms.enums.SmsMsgStatusEnum;
import com.caiyi.financial.nirvana.sms.gateway.DefaultGateWay;
import com.caiyi.financial.nirvana.sms.jedis.JedisKey;
import com.caiyi.financial.nirvana.sms.jedis.JedisService;
import com.caiyi.financial.nirvana.sms.queue.NotifyQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.ReceiveMsgQueueEntity;
import com.caiyi.financial.nirvana.sms.queue.SendQueueEntity;
import com.caiyi.financial.nirvana.sms.util.HttpClientUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 网关基类
 */
public abstract class BaseGateway extends DefaultGateWay {

    private static final Logger logger = LoggerFactory.getLogger(BaseGateway.class);

    @Override
    public void start() {
        login = true;
    }

    public static BaseGateway getGateway(String code) {
        BaseGateway gateway = null;
        StringBuilder gatewayName = new StringBuilder();
        try {
            String gatewayPackage = BaseGateway.class.getPackage().getName();
            gatewayName.append(gatewayPackage);
            gatewayName.append(".");
            gatewayName.append(code);
            Class gatewayClass = Class.forName(gatewayName.toString());
            gateway = (BaseGateway) gatewayClass.newInstance();
        } catch (Exception e) {
            logger.error("gateway not found ! gatewayName : " + gatewayName.toString());
        }
        return gateway;
    }

    @Override
    public abstract void sendMessage(SendQueueEntity entity);

    @Override
    public abstract boolean notifyStatus(NotifyQueueEntity entity);

    @Override
    public abstract boolean receiveMsg(ReceiveMsgQueueEntity entity);

    @Override
    public void close() {
        login = false;
    }

    public static String doPost(String url, String body) {
        String result = HttpClientUtil.doPost(url, body);
        if (StringUtils.isBlank(result)) {
            logger.info("two HttpClientUtil url : {}, body : {}", url, body);
            result = HttpClientUtil.doPost(url, body);
        }
        return result;
    }

    public static String doPost(String url, Map body) {
        String result = HttpClientUtil.doPost(url, body);
        if (StringUtils.isBlank(result)) {
            logger.info("two HttpClientUtil url : {}, body : {}", url, body);
            result = HttpClientUtil.doPost(url, body);
        }
        return result;
    }

    public static String doGet(String url) {
        String result = HttpClientUtil.doGet(url);
        if (StringUtils.isBlank(result)) {
            logger.info("two HttpClientUtil url : {}", url);
            result = HttpClientUtil.doGet(url);
        }
        return result;
    }

    public void handlerResponse(SendQueueEntity entity, String result, int status) {
        String[] phone = entity.getPhone().split(",");
        String[] messageId = entity.getMessageId().split(",");
        Map<String, String> map = new HashMap<>();
        for (int index = 0; index < phone.length; index++) {
            if (status == SmsMsgStatusEnum.REQUEST_SUCCESS.index) {
                map.put(result + phone[index], messageId[index]);
            }
            onSubmitResponse(status, messageId[index], result + phone[index]);
        }
        if (!map.isEmpty()) {
            JedisService.hmset(JedisKey.SMS_REMOTE_ID_MESSAGE_ID, map);
        }
    }

    public List<Element> xmlElement(String xmlDoc) {
        List<Element> children = null;
        StringReader read = null;
        try {
            if (StringUtils.isBlank(xmlDoc)) {
                return null;
            }
            //创建一个新的字符串
            read = new StringReader(xmlDoc);
            //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
            InputSource source = new InputSource(read);
            //创建一个新的SAXBuilder
            SAXBuilder sb = new SAXBuilder();
            //通过输入源构造一个Document
            Document doc = sb.build(source);
            //取的根元素
            Element root = doc.getRootElement();
            children = root.getChildren();
        } catch (Exception e) {
            logger.error("xmlElement  dom error ! ", e);
        } finally {
            read.close();
        }
        return children;
    }

    public static String doPostGb2312(String url, Map<String, String> body) {
        String httpStr = null;
        HttpPost httpPost = new HttpPost(url);
        CloseableHttpResponse response = null;
        CloseableHttpClient httpClient = HttpClients.custom().build();

        try {
            List<NameValuePair> pairList = new ArrayList<>(body.size());
            for (Map.Entry<String, String> entry : body.entrySet()) {
                NameValuePair pair = new BasicNameValuePair(entry.getKey(), entry
                        .getValue());
                pairList.add(pair);
            }
            httpPost.setEntity(new UrlEncodedFormEntity(pairList, "gb2312"));
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            httpStr = EntityUtils.toString(entity, "gb2312");
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        } finally {
            if (response != null) {
                try {
                    EntityUtils.consume(response.getEntity());
                } catch (IOException e) {
                    logger.error(e.getMessage(), e);
                }
            }
        }
        return httpStr;
    }

}
